﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace Percolation.Gui
{
    public partial class ProjectSettingsForm : Form
    {
        public ProjectSettingsForm(ProjectSettings settings)
        {
            InitializeComponent();

            m_settings = settings;
            m_algoritms = settings.getAlgorithms();
            UpdatePage();
        }

        protected ProjectSettings m_settings;
        protected AlgorithmsSettings m_algoritms;

        protected void UpdatePage()
        {
            cellTypeComboBox.SelectedIndex = 0;
            w2bTextBox.Text = m_algoritms.BoltSettings.WhiteToBlackTop.ToString();
            w2wTextBox.Text = m_algoritms.BoltSettings.WhiteToWhiteTop.ToString();
            b2bTextBox.Text = m_algoritms.BoltSettings.BlackToBlackTop.ToString();
            b2wTextBox.Text = m_algoritms.BoltSettings.BlackToWhiteTop.ToString();
            m_processCheckBox.CheckState = m_algoritms.ProcessBolt ? CheckState.Checked : CheckState.Unchecked;
        }

        protected void UpdateProperties()
        {
            m_algoritms.ProcessBolt = (m_processCheckBox.CheckState == CheckState.Checked);
            m_settings.getAlgorithms().Copy(m_algoritms);
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            UpdateProperties();
            DialogResult = System.Windows.Forms.DialogResult.OK;
            Close();
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            DialogResult = System.Windows.Forms.DialogResult.Cancel;
            Close();
        }

        private void cellTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cellTypeComboBox.SelectedIndex == 0)
            {
                w2bTextBox.Text = m_algoritms.BoltSettings.WhiteToBlackTop.ToString();
                w2wTextBox.Text = m_algoritms.BoltSettings.WhiteToWhiteTop.ToString();
                b2bTextBox.Text = m_algoritms.BoltSettings.BlackToBlackTop.ToString();
                b2wTextBox.Text = m_algoritms.BoltSettings.BlackToWhiteTop.ToString();
            }
            else if (cellTypeComboBox.SelectedIndex == 1)
            {
                w2bTextBox.Text = m_algoritms.BoltSettings.WhiteToBlackLeft.ToString();
                w2wTextBox.Text = m_algoritms.BoltSettings.WhiteToWhiteLeft.ToString();
                b2bTextBox.Text = m_algoritms.BoltSettings.BlackToBlackLeft.ToString();
                b2wTextBox.Text = m_algoritms.BoltSettings.BlackToWhiteLeft.ToString();
            }
            else if (cellTypeComboBox.SelectedIndex == 2)
            {
                w2bTextBox.Text = m_algoritms.BoltSettings.WhiteToBlackRight.ToString();
                w2wTextBox.Text = m_algoritms.BoltSettings.WhiteToWhiteRight.ToString();
                b2bTextBox.Text = m_algoritms.BoltSettings.BlackToBlackRight.ToString();
                b2wTextBox.Text = m_algoritms.BoltSettings.BlackToWhiteRight.ToString();
            }

            panelPreview.Invalidate();
        }

        private void w2bTextBox_TextChanged(object sender, EventArgs e)
        {
            if (w2bTextBox.Text.Length == 0)
                return;

            int val = System.Convert.ToInt32(w2bTextBox.Text);
            switch (cellTypeComboBox.SelectedIndex)
            {
                case 0: m_algoritms.BoltSettings.WhiteToBlackTop = val; break;
                case 1: m_algoritms.BoltSettings.WhiteToBlackLeft = val; break;
                case 2: m_algoritms.BoltSettings.WhiteToBlackRight = val; break;
            }

            panelPreview.Invalidate();
        }

        private void w2wTextBox_TextChanged(object sender, EventArgs e)
        {
            if (w2wTextBox.Text.Length == 0)
                return;

            int val = System.Convert.ToInt32(w2wTextBox.Text);
            switch (cellTypeComboBox.SelectedIndex)
            {
                case 0: m_algoritms.BoltSettings.WhiteToWhiteTop = val; break;
                case 1: m_algoritms.BoltSettings.WhiteToWhiteLeft = val; break;
                case 2: m_algoritms.BoltSettings.WhiteToWhiteRight = val; break;
            }

            panelPreview.Invalidate();
        }

        private void b2bTextBox_TextChanged(object sender, EventArgs e)
        {
            if (b2bTextBox.Text.Length == 0)
                return;

            int val = System.Convert.ToInt32(b2bTextBox.Text);
            switch (cellTypeComboBox.SelectedIndex)
            {
                case 0: m_algoritms.BoltSettings.BlackToBlackTop = val; break;
                case 1: m_algoritms.BoltSettings.BlackToBlackLeft = val; break;
                case 2: m_algoritms.BoltSettings.BlackToBlackRight = val; break;
            }

            panelPreview.Invalidate();
        }

        private void b2wTextBox_TextChanged(object sender, EventArgs e)
        {
            if (b2wTextBox.Text.Length == 0)
                return;

            int val = System.Convert.ToInt32(b2wTextBox.Text);
            switch (cellTypeComboBox.SelectedIndex)
            {
                case 0: m_algoritms.BoltSettings.BlackToWhiteTop = val; break;
                case 1: m_algoritms.BoltSettings.BlackToWhiteLeft = val; break;
                case 2: m_algoritms.BoltSettings.BlackToWhiteRight = val; break;
            }

            panelPreview.Invalidate();
        }

        private void drawSection(Graphics g, int sourceColor, int destColor, int mode, int x0, int y0, int x1, int y1, int value)
        {
            if (mode == 0)
            {
                int x2 = (x1 - x0 - 5) / 2 + x0;
                int y2 = (y1 - y0) / 2 + y0;
                g.FillRectangle(new SolidBrush(sourceColor == NetCellColor.Black ? Color.Black : Color.White),
                    x2, y1 - 15, 10, 10);

                g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x2 + 5, y0 + 20), new Point(x2 + 5, y1 - 20));
                g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x2 + 5, y0 + 20), new Point(x2, y0 + 25));
                g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x2 + 5, y0 + 20), new Point(x2 + 10, y0 + 25)); 
                

                g.FillRectangle(new SolidBrush(destColor == NetCellColor.Black ? Color.Black : Color.White),
                    x2, y0 + 5, 10, 10);

                g.DrawString(value.ToString(), new Font("Calibri", 11), new SolidBrush(Color.Black), new PointF(x2 - 10, y2));
            }
            else if (mode == 1 || mode == 2)
            {
                int x2 = (x1 - x0) / 2 + x0;
                int y2 = (y1 - y0 - 5) / 2 + y0;

                g.FillRectangle(new SolidBrush(sourceColor == NetCellColor.Black ? Color.Black : Color.White),
                    (mode == 1) ? x1 - 15 : x0 + 5, y2, 10, 10);

                g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x0 + 20, y2 + 5), new Point(x1 - 20, y2 + 5));
                if (mode == 1)
                {
                    g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x0 + 20, y2 + 5), new Point(x0 + 25, y2));
                    g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x0 + 20, y2 + 5), new Point(x0 + 25, y2 + 10));
                }
                else if (mode == 2)
                {
                    g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x1 - 20, y2 + 5), new Point(x1 - 25, y2));
                    g.DrawLine(new Pen(new SolidBrush(Color.Black)), new Point(x1 - 20, y2 + 5), new Point(x1 - 25, y2 + 10));
                }

                g.FillRectangle(new SolidBrush(destColor == NetCellColor.Black ? Color.Black : Color.White),
                    (mode == 1) ? x0 + 5 : x1 - 15, y2, 10, 10);

                g.DrawString(value.ToString(), new Font("Calibri", 11), new SolidBrush(Color.Black), new PointF(x2, y2 - 10));

            }
        }

        private void drawPreview(Graphics g, int w2b, int w2w, int b2b, int b2w, int mode)
        {
            if (mode == 0)
            {
                int wid = panelPreview.Width / 4;
                int hei = panelPreview.Height;
                drawSection(g, NetCellColor.White, NetCellColor.Black, mode, 0, 0, wid, hei, w2b);
                drawSection(g, NetCellColor.White, NetCellColor.White, mode, wid, 0, 2 * wid, hei, w2w);
                drawSection(g, NetCellColor.Black, NetCellColor.Black, mode, 2 * wid, 0, 3 * wid, hei, b2b);
                drawSection(g, NetCellColor.Black, NetCellColor.White, mode, 3 * wid, 0, 4 * wid, hei, b2w);
            }
            else if (mode == 1 || mode == 2)
            {
                int wid = panelPreview.Width / 2;
                int hei = panelPreview.Height / 2;
                drawSection(g, NetCellColor.White, NetCellColor.Black, mode, 0, 0, wid, hei, w2b);
                drawSection(g, NetCellColor.White, NetCellColor.White, mode, wid, 0, 2 * wid, hei, w2w);
                drawSection(g, NetCellColor.Black, NetCellColor.Black, mode, 0, hei, wid, 2 * hei, b2b);
                drawSection(g, NetCellColor.Black, NetCellColor.White, mode, wid, hei, 2 * wid, 2 * hei, b2w);

            }
        }

        private void panelPreview_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(new SolidBrush(Color.Tomato), 0, 0, panelPreview.Width, panelPreview.Height);

            EdgeWeightSettings s = m_algoritms.BoltSettings;
            switch (cellTypeComboBox.SelectedIndex)
            {
                case 0: drawPreview(e.Graphics, s.WhiteToBlackTop, s.WhiteToWhiteTop, s.BlackToBlackTop, s.BlackToWhiteTop, 0); break;
                case 1: drawPreview(e.Graphics, s.WhiteToBlackLeft, s.WhiteToWhiteLeft, s.BlackToBlackLeft, s.BlackToWhiteLeft, 1); break;
                case 2: drawPreview(e.Graphics, s.WhiteToBlackRight, s.WhiteToWhiteRight, s.BlackToBlackRight, s.BlackToWhiteRight, 2); break;
            }
        }
    }
}
